﻿using FTBS.Models.BLO;
using FTBS.Models.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PagedList;
using FTBS.Models.Entities.Concert;
using System.IO;

namespace FTBS.Controllers
{
    public class FilmController : Controller
    {
        private FilmBLO _boFilm = new FilmBLO();
        private CategoryBLO _bloCate = new CategoryBLO();
        private FormatBLO _bloFormat = new FormatBLO();
        private ScheduleBLO _scheduleBlo = new ScheduleBLO();
        private TicketBLO _ticketBlo = new TicketBLO();

        #region Film Admin
        /// <summary>
        /// Redirect to Index page. Load all film into list
        /// </summary>
        /// <returns></returns>
        public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page, bool? isSortDescending)
        {
            if (this.Session["RoleName"] == null || this.Session["UserName"] == null || this.Session["Account"] == null || this.Session["RoleName"].ToString().Trim() != "Staff")
            {
                return Redirect("/Home/Announcement");
            }

            List<Film> listFilm = new List<Film>();
            listFilm = _boFilm.LoadFilms();
            ViewBag.NameSortParm = "film_name_desc";
            ViewBag.CurrentSort = sortOrder;

            if (searchString != null)
            {
                page = 1;
            }
            else
            {
                searchString = currentFilter;
            }
            ViewBag.CurrentFilter = searchString;
            ViewBag.IsSortDes = false;

            if (!String.IsNullOrEmpty(searchString))
            {
                listFilm = listFilm.Where(film => film.Name.ToUpper().Contains(searchString.ToUpper())
                                  || film.Length.ToString().ToUpper().Contains(searchString.ToUpper())
                                  || film.Nation.ToUpper().Contains(searchString.ToUpper())
                                  || film.AgeLimit.ToString().ToUpper().Contains(searchString.ToUpper())
                                  || film.Format.FormatName.ToUpper().Contains(searchString.ToUpper())
                                  || film.Category.CategoryName.ToUpper().Contains(searchString.ToUpper())).ToList();
            }


            switch (sortOrder)
            {
                case "film_name_desc":
                    if (isSortDescending == true)
                    {
                        listFilm = listFilm.OrderByDescending(film => film.Name).ToList();
                        ViewBag.IsSortDes = false;
                    }
                    else
                    {
                        listFilm = listFilm.OrderBy(film => film.Name).ToList();
                        ViewBag.IsSortDes = true;
                    }
                    break;
                case "length_desc":
                    if (isSortDescending == true)
                    {
                        listFilm = listFilm.OrderByDescending(film => film.Length).ToList();
                        ViewBag.IsSortDes = false;
                    }
                    else
                    {
                        listFilm = listFilm.OrderBy(film => film.Length).ToList();
                        ViewBag.IsSortDes = true;
                    }
                    break;
                case "nation_desc":
                    if (isSortDescending == true)
                    {
                        listFilm = listFilm.OrderByDescending(film => film.Nation).ToList();
                        ViewBag.IsSortDes = false;
                    }
                    else
                    {
                        listFilm = listFilm.OrderBy(film => film.Nation).ToList();
                        ViewBag.IsSortDes = true;
                    }
                    break;
                case "age_desc":
                    if (isSortDescending == true)
                    {
                        listFilm = listFilm.OrderByDescending(film => film.AgeLimit).ToList();
                        ViewBag.IsSortDes = false;
                    }
                    else
                    {
                        listFilm = listFilm.OrderBy(film => film.AgeLimit).ToList();
                        ViewBag.IsSortDes = true;
                    }
                    break;
                case "format_desc":
                    if (isSortDescending == true)
                    {
                        listFilm = listFilm.OrderByDescending(film => film.Format.FormatName).ToList();
                        ViewBag.IsSortDes = false;
                    }
                    else
                    {
                        listFilm = listFilm.OrderBy(film => film.Format.FormatName).ToList();
                        ViewBag.IsSortDes = true;
                    }
                    break;
                case "category_desc":
                    if (isSortDescending == true)
                    {
                        listFilm = listFilm.OrderByDescending(film => film.Category.CategoryName).ToList();
                        ViewBag.IsSortDes = false;
                    }
                    else
                    {
                        listFilm = listFilm.OrderBy(film => film.Category.CategoryName).ToList();
                        ViewBag.IsSortDes = true;
                    }
                    break;
                default:
                    listFilm = listFilm.OrderBy(film => film.Name).ToList();
                    ViewBag.IsSortDes = false;
                    break;
            }

            int pageSize = 5;
            int pageNumber = (page ?? 1);

            return View(listFilm.ToPagedList(pageNumber, pageSize));
        }

        /// <summary>
        /// Load Film Detail
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>      
        /// <author>DuyHDV</author>
        /// <date>2014/03/30</date>
        public ActionResult Details(int id)
        {
            if (this.Session["RoleName"] == null || this.Session["UserName"] == null || this.Session["Account"] == null || this.Session["RoleName"].ToString().Trim() != "Staff")
            {
                return Redirect("/Home/Announcement");
            }
            Film film = _boFilm.LoadFilmsById(id);
            ViewBag.category = _bloCate.LoadCategoryById(film.CategoryId).CategoryName;
            ViewBag.format = _bloFormat.LoadFormatsById(film.FormatId).FormatName;
            return View(film);
        }


        /// <summary>
        /// Create a film
        /// </summary>
        /// <returns></returns>
        public ActionResult Create()
        {
            if (this.Session["RoleName"] == null || this.Session["UserName"] == null || this.Session["Account"] == null || this.Session["RoleName"].ToString().Trim() != "Staff")
            {
                return Redirect("/Home/Announcement");
            }
            ViewBag.FilmName = null;
            ViewBag.CategoryId = new SelectList(_bloCate.LoadCategories(), "CategoryId", "CategoryName");
            ViewBag.FormatId = new SelectList(_bloFormat.LoadFormats(), "FormatId", "FormatName");
            return View();
        }

        /// <summary>
        /// Show partial view for CategoryPartial, is used when user want add new Category from CreateFilm form
        /// </summary>
        /// <param name="categoryModel"></param>
        /// <returns>Show partial view Category</returns>
        /// <author>vuongvt</author>
        /// <date>2014/03/03</date>
        public PartialViewResult CategoryPartial(Category categoryModel)
        {
            return PartialView("CategoryPartial", categoryModel);
        }

        /// <summary>
        /// Show partial view for FormatPartial, is used when user want add new Format from CreateFilm form
        /// </summary>
        /// <param name="categoryModel"></param>
        /// <returns>Show partial view Format</returns>
        /// <author>vuongvt</author>
        /// <date>2014/03/03</date>
        public PartialViewResult FormatPartial(Format formatModel)
        {
            return PartialView("FormatPartial", formatModel);
        }

        /// <summary>
        /// Create a new Category from CreateFilm
        /// </summary>
        /// <param name="categoryModel"></param>
        /// <returns>Redirect to CreateFilm page after create new Category</returns>
        /// <author>vuongvt</author>
        /// <date>2014/03/03</date>
        [HttpPost]
        public PartialViewResult CreateCategoryPartial(Category categoryModel)
        {
            if (ModelState.IsValid)
            {
                _bloCate.CreateCategory(categoryModel);
            }

            ViewBag.CategoryId = new SelectList(_bloCate.LoadCategories(), "CategoryId", "CategoryName");
            ViewBag.FormatId = new SelectList(_bloFormat.LoadFormats(), "FormatId", "FormatName");
            return PartialView("Create");
        }

        /// <summary>
        /// Create a new Format from CreateFilm
        /// </summary>
        /// <param name="categoryModel"></param>
        /// <returns>Redirect to CreateFilm page after create new Format</returns>
        /// <author>vuongvt</author>
        /// <date>2014/03/03</date>
        [HttpPost]
        public PartialViewResult CreateFormatPartial(Format formatModel)
        {
            if (ModelState.IsValid)
            {
                _bloFormat.CreateFormat(formatModel);
            }

            ViewBag.CategoryId = new SelectList(_bloCate.LoadCategories(), "CategoryId", "CategoryName");
            ViewBag.FormatId = new SelectList(_bloFormat.LoadFormats(), "FormatId", "FormatName");
            return PartialView("Create");
        }

        /// <summary>
        /// Create a film. Save film and image of film
        /// </summary>
        /// <param name="film"></param>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Create(Film film, List<HttpPostedFileBase> ImageURL)
        {
            if (this.Session["RoleName"] == null || this.Session["UserName"] == null || this.Session["Account"] == null || this.Session["RoleName"].ToString().Trim() != "Staff")
            {
                return Redirect("/Home/Announcement");
            }
            if (ModelState.IsValid && ImageURL[1]!=null&& ImageURL[0]!=null)
            {
                if (!_boFilm.IsFilmExistedCreate(film))
                {
                   
                        ImageURL[0].SaveAs(HttpContext.Server.MapPath("~/Image/FilmImage/") + ImageURL[0].FileName);
                        film.ImageURL = ImageURL[0].FileName;
                       // Save Horizontal Image for show in slider
                        ImageURL[1].SaveAs(HttpContext.Server.MapPath("~/Image/FilmImage/Horizontal/") + ImageURL[0].FileName);
                   
                    ViewBag.FilmName = null;
                    _boFilm.CreateFilm(film);
                    return RedirectToAction("Index");
                }
                else
                {
                    ViewBag.FilmName = film.Name;
                    ViewBag.CategoryId = new SelectList(_bloCate.LoadCategories(), "CategoryId", "CategoryName");
                    ViewBag.FormatId = new SelectList(_bloFormat.LoadFormats(), "FormatId", "FormatName");
                    return View(film);
                }
            }
            else
            {
                ViewBag.FilmName = null;
                ViewBag.CategoryId = new SelectList(_bloCate.LoadCategories(), "CategoryId", "CategoryName", film.CategoryId);
                ViewBag.FormatId = new SelectList(_bloFormat.LoadFormats(), "FormatId", "FormatName", film.FormatId);
                return View(film);
            }
        }

        public ActionResult Edit(int id = 0)
        {
            if (this.Session["RoleName"] == null || this.Session["UserName"] == null || this.Session["Account"] == null || this.Session["RoleName"].ToString().Trim() != "Staff")
            {
                return Redirect("/Home/Announcement");
            }
            if (_boFilm.IsFilmUsingAndHaveBookedTicket(id))
            {
                TempData["CanNotEdit"] = true;
                return RedirectToAction("Index");
            }
            else
            {
                TempData["CanNotEdit"] = null;
                ViewBag.FilmName = null;
                Film film = _boFilm.LoadFilmsById(id);
                if (film == null)
                {
                    return HttpNotFound();
                }
                ViewBag.CategoryId = _bloCate.LoadCategories();
                ViewBag.FormatId = _bloFormat.LoadFormats();
                return View(film);
            }
        }

        [HttpPost]
        public ActionResult Edit(Film film, HttpPostedFileBase fileImage, HttpPostedFileBase fileImageHorizontal,string cate, string format)
        {
            if (this.Session["RoleName"] == null || this.Session["UserName"] == null || this.Session["Account"] == null || this.Session["RoleName"].ToString().Trim() != "Staff")
            {
                return Redirect("/Home/Announcement");
            }
            film.CategoryId = Convert.ToInt32(cate);
            film.FormatId = Convert.ToInt32(format);
            var filmId = film.FilmId;
                if (!_boFilm.IsFilmExistedUpdate(film))
                {
                    if (fileImage != null)
                    {
                      
                            System.IO.File.Delete(HttpContext.Server.MapPath("~/Image/FilmImage/") + film.ImageURL);
                            fileImage.SaveAs(HttpContext.Server.MapPath("~/Image/FilmImage/") + film.ImageURL);
                            

                            if (fileImageHorizontal != null)
                            {
                                //Save Horizontal Image for show in slider
                              
                                System.IO.File.Delete(HttpContext.Server.MapPath("~/Image/FilmImage/Horizontal/") + film.ImageURL);
                                fileImageHorizontal.SaveAs(HttpContext.Server.MapPath("~/Image/FilmImage/Horizontal/") + film.ImageURL);
                           
                            }
                         
                        
                     
                    }
                    else if(fileImage==null && fileImageHorizontal!=null){
                       System.IO.File.Delete(HttpContext.Server.MapPath("~/Image/FilmImage/Horizontal/") + film.ImageURL); 
                      
                                //Save Horizontal Image for show in slider
                       fileImageHorizontal.SaveAs(HttpContext.Server.MapPath("~/Image/FilmImage/Horizontal/") + film.ImageURL);
                    }
                    var resultEdit = _boFilm.EditFilm(film);
                    if (resultEdit)
                    {
                        return RedirectToAction("Index");
                    }
                    else
                    {
                        ViewBag.FilmName = null;
                        ViewBag.CategoryId = _bloCate.LoadCategories();
                        ViewBag.FormatId = _bloFormat.LoadFormats();
                        return View(film);
                    }
                }
     
            ViewBag.FilmName = null;
            ViewBag.CategoryId = _bloCate.LoadCategories();
            ViewBag.FormatId = _bloFormat.LoadFormats();
            return View(film);
        }

        /// <summary>
        /// Delete a film based on FilmId
        /// </summary>
        /// <param name="id"></param>
        /// <returns>Redirect to Index page</returns>
        /// <author>nguyen</author>
        [HttpDelete, ActionName("Delete")]
        public ActionResult Delete(int id = 0)
        {
            if (this.Session["RoleName"] == null || this.Session["UserName"] == null || this.Session["Account"] == null || this.Session["RoleName"].ToString().Trim() != "Staff")
            {
                return Redirect("/Home/Announcement");
            }
            if (_boFilm.IsFilmUsedForSchedule(id))
            {
                TempData["CanNotDelete"] = true;
                return RedirectToAction("Index");
            }
            else
            {
                Film film = _boFilm.LoadFilmsById(id);
                if (film == null)
                {
                    return HttpNotFound();
                }
                _boFilm.DeleteFilm(film);
                return RedirectToAction("Index");
            }
        }


        /// <summary>
        /// Load Film Detail
        /// </summary>
        /// <returns></returns>
        public ActionResult Detail(int filmId)
        {
            if (this.Session["RoleName"] == null || this.Session["UserName"] == null || this.Session["Account"] == null || this.Session["RoleName"].ToString().Trim() != "Staff")
            {
                return Redirect("/Home/Announcement");
            }
            var film = _boFilm.LoadFilmById(filmId);
            return View(film);
        }
        #endregion
        #region Film View
        public ActionResult ShowingFilm()
        {
            List<Schedule> listScheduleShowing = new List<Schedule>();
            listScheduleShowing = _scheduleBlo.GetSchedulesShowing();
            ViewBag.ListSchedule = listScheduleShowing;
            var listFilmShowing = _scheduleBlo.GetListOfFilmShowing();
            return View(listFilmShowing);
        }
        public ActionResult PromotionFilm()
        {
            List<Schedule> listScheduleShowing = new List<Schedule>();
            listScheduleShowing = _scheduleBlo.GetSchedulesPro();
            ViewBag.ListSchedule = listScheduleShowing;
            var listProShowing = _scheduleBlo.GetListOListPromotion();
            return View(listProShowing);
        }
        public ActionResult HotFilm()
        {
            List<Ticket> listTicket = new List<Ticket>();
            listTicket = _scheduleBlo.GetListTicket();
            //ViewBag.ListHot = listTicket;
            List<Film> listFilmShowing = _scheduleBlo.GetListOfFilmShowing();
            Dictionary<int, int> listFilmCount = new Dictionary<int, int>();
            foreach (var film in listFilmShowing)
            {
                int countTicket = 0;
                foreach (var ticket in listTicket)
                {
                    if (film.FilmId == ticket.Schedule.FilmId)
                    {
                        countTicket = countTicket + 1;
                    }
                }
                if (countTicket > 0)
                {
                    listFilmCount.Add(film.FilmId, countTicket);
                }
            }
            //var listSorted = listFilmCount.Values.ToList();
            //listSorted.Sort();
            //listSorted.Reverse();
            var listSorted = from item in listFilmCount
                             orderby item.Value descending
                             select item;

            List<Film> listHotFilm = new List<Film>();
            foreach (var item in listFilmShowing)
            {
                foreach (var dicItem in listSorted)
                {
                    if (item.FilmId == dicItem.Key)
                    {
                        listHotFilm.Add(item);
                    }
                }
            }
            List<Schedule> listAllSchedule = new List<Schedule>();
            listAllSchedule = _scheduleBlo.GetSchedulesShowing();
            ViewBag.ListSchedule = listAllSchedule;

            return View(listHotFilm);
        }
        public ActionResult ComingFilm()
        {
            List<Schedule> listScheduleComing = new List<Schedule>();
            listScheduleComing = _scheduleBlo.GetSchedulesComing();
            ViewBag.ListSchedule = listScheduleComing;
            var listFilmCommingSoon = _scheduleBlo.GetListOfFilmComing();
            return View(listFilmCommingSoon);
        }
        #endregion

        #region List all films order by type

        /// <summary>
        /// List all showing films
        /// </summary>
        /// <returns></returns>         
        /// <author>DuyHDV</author>
        public ActionResult ListShowingFilms() {
            List<Film> listFilms = new List<Film>();
            ViewBag.Formats = _bloFormat.LoadFormats();
            listFilms = _boFilm.GetAllShowingFilms();
            return View(listFilms);
        }

        /// <summary>
        /// List all films, which are showing and have the promotion
        /// </summary>
        /// <returns></returns>     
        /// <author>DuyHDV</author>
        public ActionResult ListPromotionalFilms()
        {
            List<Film> listFilms = new List<Film>();
            ViewBag.Formats = _bloFormat.LoadFormats();
            listFilms = _boFilm.GetAllPromotionalFilms();
            return View(listFilms);
        }

        /// <summary>
        /// List all hot films of a week
        /// </summary>                   
        /// <returns></returns>
        /// <author>DuyHDV</author>
        public ActionResult ListHotFilms()
        {
            List<Film> listFilms = new List<Film>();
            ViewBag.Formats = _bloFormat.LoadFormats();
            List<Ticket> listTickets = new List<Ticket>();
            listTickets = _scheduleBlo.GetListTicket();
            List<Film> showingFilms = _boFilm.GetAllShowingFilms();
            Dictionary<Film, int> listFilmCount = new Dictionary<Film, int>();
            foreach (var film in showingFilms)
            {
                int countTicket = 0;
                foreach (var ticket in listTickets)
                {
                    if (film.FilmId == ticket.Schedule.FilmId)
                    {
                        countTicket = countTicket + 1;
                    }
                }
                if (countTicket > 0)
                {
                    listFilmCount.Add(film, countTicket);
                }
            }
            var listSortedFilms = (from item in listFilmCount
                                   orderby item.Value descending
                                   select item.Key).ToList();
            listFilms = listSortedFilms;
            return View(listFilms);
        }

        /// <summary>
        /// List all coming films
        /// </summary>                   
        /// <returns></returns>
        /// <author>DuyHDV</author>
        public ActionResult ListComingFilms()
        {
            List<Film> listFilms = new List<Film>();
            ViewBag.Formats = _bloFormat.LoadFormats();
            listFilms = _boFilm.GetAllComingFilms();
            return View(listFilms);
        }
        #endregion
    }
}


